#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>





/*----------------------Creer codage--------------------*/
void creer_code(struct arbre_huff *arbre, int code, int niveau, struct dictionaire dico[])
{
	/* Condition d'arret de la fonction r�cursive : si on est sur une feuille */
	if((arbre->gauche==NULL)&&(arbre->droite==NULL))
	{
		arbre->code=code;
		arbre->bits=niveau;
		/* Cr�ation du dictionaire */
		dico[arbre->c].code=code;
		dico[arbre->c].bits=niveau;
		return;
	}

	/* On part sur la gauche */
	if(arbre->gauche!=NULL)
		creer_code(arbre->gauche,(code<<1),niveau+1,dico); /* La branche qui part � gauche est celle des 0 */

	/* On part sur la droite */
	if(arbre->droite!=NULL)
		creer_code(arbre->droite,(code<<1)+1,niveau+1,dico); /* La branche qui part � droite est celle des 1 */
}


/*---------------------Encodage du fichier------------------------------*/
/* A partir du dictionaire on parcours le fichier � compresser en  rempla�ant le caract�re par son codage, ce codage est enregistr� dans un buffer.
    Lorsque le buffer est plein on l'enregistre dans  l'archive. */

unsigned int encodage(struct dictionaire dico[], char nom[])
{
	FILE *F, *FTMP; /* Fichiers source et destination */
	char nomfich[90];
	int i;
	int charlu; /* Caract�re courant lu dans le fichier */
	unsigned int buffer; /* Stockage tant qu'on ne peut pas ecrire un octet */
	unsigned char code; /* Codage de huffman du caract�re */
	unsigned short int taille_buffer; /* Nombre de bits significatifs du buffer */
	unsigned int taille_fich; /* Taille du fichier � compresser en octets */

	/* R�cuperation du nom de fichier */
	for(i=strlen(nom);(charlu=nom[i])!='\\';i--);
	strcpy(nomfich,"C:\\");
	strcat(nomfich,&nom[i]);
	strcat(nomfich,".tmp");

	if( (FTMP=fopen(nomfich,"wb"))==NULL)
	{
		perror("Erreur => ouverture du fichier .tmp ");
		exit(EXIT_FAILURE);
	}
	if((F=fopen(nom,"rb"))==NULL)
	{
		perror("Erreur => ouverture du fichier � compresser ");
		exit(EXIT_FAILURE);
	}

	taille_buffer=0;
	buffer=0;
	taille_fich=0;
	while((charlu=fgetc(F))!=EOF)
	{
		buffer=buffer << dico[charlu].bits; /* D�calage du nombre de bits n�cessaire au caract�re � coder */
		buffer=buffer | dico[charlu].code; /* Masque binaire afin de concatener la valeur */
		taille_buffer=taille_buffer+dico[charlu].bits;

		/* Ecriture du buffer dans le fichier losque celui-ci est plein */
		while(taille_buffer>=8)
		{
			taille_buffer=taille_buffer-8; /* Taille apr�s l'enregistrement */
			code=buffer>>taille_buffer; /* On prend le premier caract�re � enregister */
			fputc(code,FTMP);
		}
		taille_fich++;
	}
	/* Enregistrement du buffer en cours */
	if(taille_buffer)
	{
		buffer=buffer<<(8-taille_buffer); /* On met les derniers bits � 0 */
		fputc(buffer,FTMP);
	}

	fclose(F);
	fclose(FTMP);
	return taille_fich;
}
